﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/*
 享元模式的优点在于：减少了运行时对象实例的个数，节省了内存，并且可以集中管理对象的多个状态。

缺点也很明显：个体之间无法相对独立，拥有不同的行为。
     */
public abstract class LevelData
{
    protected virtual void LoadFromFile(string filePath)
    {
        //TODO:
    }
    public abstract int GetAttack(ClientData data);
    public abstract int GetLevelAttack(int lv);

}

public class MonsterLevelData : LevelData
{
    public int ID { get; private set; }
    public MonsterLevelData(int monID)
    {
        ID = monID;
        //For different heroes, load different files.
        LoadFromFile(monID.ToString());
    }

    private List<int> _levelAttackList = new List<int>();//Loaded in the method LoadFromFile
    protected override void LoadFromFile(string filePath)
    {
        base.LoadFromFile(filePath);
        //TEST
        for (int i = 1; i <= 10; i++)
        {
            _levelAttackList.Add(i * 10);
        }
    }

    public override int GetAttack(ClientData data)
    {
        int lv = data.Level;
        lv = System.Math.Min(System.Math.Max(lv, 1), 10);
        int attack = _levelAttackList[lv - 1];
        return attack + data.AttackPlus;
    }

    public override int GetLevelAttack(int lv)
    {
        lv = System.Math.Min(System.Math.Max(lv, 1), 10);
        return _levelAttackList[lv - 1];
    }

}

public class ClientData
{
    public int Level { get; set; }
    public int AttackPlus { get; set; }
}


public class Monster : ClientData
{
    LevelData _levelData;
    public Monster(int monID)
    {
        _levelData = LevelDataFactory.GetMonsterLevelData(monID);
    }
    public int GetAttack()
    {
        return _levelData.GetLevelAttack(Level) + AttackPlus;
    }
}



public static class LevelDataFactory
{
    public static Dictionary<int, LevelData> _monsterLevelData = new Dictionary<int, LevelData>();
    public static LevelData GetMonsterLevelData(int monID)
    {
        if (!_monsterLevelData.ContainsKey(monID))
        {
            _monsterLevelData[monID] = new MonsterLevelData(monID);
        }
        return _monsterLevelData[monID];
    }
}


public class FLyWeight : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        //LevelData levelData = LevelDataFactory.GetMonsterLevelData(1);
        //ClientData monster = new ClientData();
        //monster.Level = 3;
        //monster.AttackPlus = 5;
        //Debug.Log(levelData.GetAttack(monster));

        Monster mon = new Monster(2);
        mon.Level = 3;
        mon.AttackPlus = 4;
        Debug.Log(mon.GetAttack());



    }


}
